/*
 * Copyright 2000-2005 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jetbrains.idea.accurev;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;

import java.io.*;

public final class StreamGobbler implements Runnable {
  private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.accurev.StreamGobbler");
  private final static int IN_MEMORY_RESULT_THRESHOULD = 48 * 1024; // 48K

  private OutputStream myByteContents;
  private final InputStream is;
  private File myTempFile = null;
  private int myOutputLength = 0;

  public StreamGobbler(final InputStream is) {
    this.is = is;
    myByteContents = new ByteArrayOutputStream();
  }

  public void run() {
    byte[] buffer = new byte[8 * 1024];
    try {
      int read;
      while (((read = is.read(buffer, 0, buffer.length)) != -1)) {
        myByteContents.write(buffer, 0, read);
        myOutputLength += read;

        if (myTempFile == null && myOutputLength > IN_MEMORY_RESULT_THRESHOULD) {
          switchToTemporaryFileContent();
        }
      }

      myByteContents.close();
    }
    catch (IOException ioe) {
      LOG.error(ioe);
    }
  }

  private void switchToTemporaryFileContent() {
    try {
      myTempFile = File.createTempFile("idea_p4", "command.output");
      ByteArrayOutputStream oldStream = (ByteArrayOutputStream)myByteContents;
      myByteContents = new BufferedOutputStream(new FileOutputStream(myTempFile));
      oldStream.writeTo(myByteContents);
    }
    catch (IOException e) {
      LOG.error(e);
      myTempFile = null;
    }
  }

  public int getResultLength() {
    return myOutputLength;
  }

  public InputStream getResultAsStream() {
    try {
      if (myTempFile != null) {
        return new BufferedInputStream(new FileInputStream(myTempFile));
      }
      else {
        return new ByteArrayInputStream(((ByteArrayOutputStream)myByteContents).toByteArray());
      }
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  protected void finalize() throws Throwable {
    super.finalize();

    if (myTempFile != null) {
      FileUtil.delete(myTempFile);
    }
  }
}

